from tortoise import fields, models
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException
from tortoise.contrib.fastapi import register_tortoise
from tortoise.queryset import Q
from tortoise import Tortoise
from typing import Union
from contextlib import asynccontextmanager


class User(models.Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=255, null=False)
    email = fields.CharField(max_length=255, null=False)

    class Meta:
        ordering = ["id"]


class CreateUser(BaseModel):
    name: str
    email: str


class UpdateUser(BaseModel):
    name: str
    email: str


# async def init():
#     await Tortoise.init(db_url="sqlite://db.sqlite3",
#                         modules={"models": ["models", "__main__"]})
#     await Tortoise.generate_schemas()

# @asynccontextmanager
# async def lifespan(app: FastAPI):
#     await init()
#     yield
#     await Tortoise.close_connections()

app = FastAPI(
    title="用户管理 API",
    description="这是一个使用 FastAPI 和 Tortoise ORM 构建的用户管理 API",
    version="1.0.0",
)

register_tortoise(
    app,
    db_url="sqlite://db.sqlite3",
    modules={"models": ['main']},
    generate_schemas=True,
    add_exception_handlers=True,
)


@app.post("/users/", response_model=None, summary="创建新用户")
async def create_user(user: CreateUser) -> Union[User, dict, None]:
    """
    创建一个新用户
    
    - **name**: 用户名
    - **email**: 用户邮箱
    """
    user_obj = await User.create(**user.model_dump())
    return await User.get(id=user_obj.id)


@app.get("/users/{user_id}", response_model=None, summary="获取用户信息")
async def read_user(user_id: int) -> Union[User, dict, None]:
    """
    根据用户ID获取用户信息
    
    - **user_id**: 用户ID
    """
    return await User.get_or_none(id=user_id)


@app.put("/users/{user_id}", response_model=None, summary="更新用户信息")
async def update_user(user_id: int,
                      user: UpdateUser) -> Union[User, dict, None]:
    """
    更新指定用户的信息
    
    - **user_id**: 要更新的用户ID
    - **name**: 新的用户名
    - **email**: 新的用户邮箱
    """
    await User.filter(id=user_id).update(**user.model_dump(exclude_unset=True))
    return await User.get_or_none(id=user_id)


@app.delete("/users/{user_id}", response_model=None, summary="删除用户")
async def delete_user(user_id: int) -> Union[User, dict, None]:
    """
    删除指定的用户
    
    - **user_id**: 要删除的用户ID
    """
    deleted_count = await User.filter(id=user_id).delete()
    if not deleted_count:
        raise HTTPException(status_code=404, detail=f"用户 {user_id} 不存在")
    return {"ok": True}


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
